package top.continew.minithreadpool.ui.techUi;

import top.continew.minithreadpool.concurrent.ThreadPool;
import top.continew.minithreadpool.concurrent.ThreadPoolExecutor;
import top.continew.minithreadpool.concurrent.ThreadPoolFactory;
import top.continew.minithreadpool.factory.DefaultThreadFactory;
import top.continew.minithreadpool.policy.AbortPolicy;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class TechThreadPoolVisualizer extends JFrame {
    private ThreadPoolExecutor threadPool;
    private Timer timer;

    // UI 组件
    private JLabel coreSizeLabel;
    private JLabel maxSizeLabel;
    private JLabel activeThreadsLabel;
    private JLabel queueSizeLabel;
    private JLabel completedTasksLabel;
    private JLabel stateLabel;

    private TechTaskQueuePanel techTaskQueuePanel;
    private JTextArea logArea;

    private JButton startButton;
    private JButton stopButton;
    private JButton submitButton;
    private JButton resizeButton;

    private JSpinner taskCountSpinner;
    private JSpinner corePoolSizeSpinner;
    private JSpinner maxPoolSizeSpinner;

    // 科技风颜色
    private static final Color BACKGROUND = new Color(15, 23, 42); // 深蓝黑
    private static final Color PRIMARY = new Color(0, 195, 255);   // 霓虹蓝
    private static final Color SECONDARY = new Color(255, 0, 128); // 霓虹粉
    private static final Color ACCENT = new Color(0, 255, 163);   // 霓虹绿
    private static final Color TEXT_COLOR = new Color(220, 220, 220);

    public TechThreadPoolVisualizer() {
        super("线程池教学工具 - 科技风");
        setSize(1200, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 设置科技风外观
        UIManager.put("Panel.background", BACKGROUND);
        UIManager.put("Label.foreground", TEXT_COLOR);
        UIManager.put("TitledBorder.titleColor", PRIMARY);
        UIManager.put("TextArea.background", new Color(25, 35, 55));
        UIManager.put("TextArea.foreground", TEXT_COLOR);
        UIManager.put("TextArea.caretForeground", PRIMARY);

        // 初始化线程池
        threadPool = ThreadPoolFactory.createFixedThreadPool(4);

        // 创建UI组件
        createUI();

        // 启动状态更新定时器
        startStatusTimer();

        // 设置窗口居中
        setLocationRelativeTo(null);
    }

    private void createUI() {
        // 主面板 - 使用渐变背景
        JPanel mainPanel = new GradientPanel(BACKGROUND, new Color(10, 18, 35));
        mainPanel.setLayout(new BorderLayout());
        mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

        // 标题
        JLabel titleLabel = new JLabel("线程池教学工具", SwingConstants.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 28));
        titleLabel.setForeground(PRIMARY);
        titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));
        mainPanel.add(titleLabel, BorderLayout.NORTH);

        // 内容面板
        JPanel contentPanel = new JPanel(new BorderLayout(20, 20));
        contentPanel.setOpaque(false);

        // 左侧控制面板
        JPanel leftPanel = new JPanel(new GridLayout(3, 1, 20, 20));
        leftPanel.setOpaque(false);

        // 线程池配置面板
        JPanel configPanel = createTechPanel("线程池配置", new Color(25, 35, 55));
        configPanel.setLayout(new GridLayout(4, 2, 10, 10));

        JLabel coreSizeText = createTechLabel("核心线程数:");
        corePoolSizeSpinner = createTechSpinner(4, 1, 20);
        JLabel maxSizeText = createTechLabel("最大线程数:");
        maxPoolSizeSpinner = createTechSpinner(4, 1, 20);

        configPanel.add(coreSizeText);
        configPanel.add(corePoolSizeSpinner);
        configPanel.add(maxSizeText);
        configPanel.add(maxPoolSizeSpinner);

        // 状态面板
        JPanel statusPanel = createTechPanel("线程池状态", new Color(25, 35, 55));
        statusPanel.setLayout(new GridLayout(4, 2, 10, 10));

        JLabel activeThreadsText = createTechLabel("活跃线程:");
        activeThreadsLabel = createTechValueLabel("0");
        JLabel queueSizeText = createTechLabel("队列大小:");
        queueSizeLabel = createTechValueLabel("0");
        JLabel completedTasksText = createTechLabel("完成任务:");
        completedTasksLabel = createTechValueLabel("0");
        JLabel stateText = createTechLabel("状态:");
        stateLabel = createTechValueLabel("运行中");

        statusPanel.add(activeThreadsText);
        statusPanel.add(activeThreadsLabel);
        statusPanel.add(queueSizeText);
        statusPanel.add(queueSizeLabel);
        statusPanel.add(completedTasksText);
        statusPanel.add(completedTasksLabel);
        statusPanel.add(stateText);
        statusPanel.add(stateLabel);

        // 控制按钮面板
        JPanel buttonPanel = createTechPanel("控制", new Color(25, 35, 55));
        buttonPanel.setLayout(new GridLayout(4, 1, 15, 15));

        startButton = createTechButton("启动线程池", PRIMARY);
        stopButton = createTechButton("停止线程池", SECONDARY);
        submitButton = createTechButton("提交任务", ACCENT);
        resizeButton = createTechButton("调整线程池", PRIMARY);

        startButton.addActionListener(e -> startThreadPool());
        stopButton.addActionListener(e -> stopThreadPool());
        submitButton.addActionListener(e -> submitTasks());
        resizeButton.addActionListener(e -> resizeThreadPool());

        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);
        buttonPanel.add(submitButton);
        buttonPanel.add(resizeButton);

        // 添加面板到左侧
        leftPanel.add(configPanel);
        leftPanel.add(statusPanel);
        leftPanel.add(buttonPanel);

        // 任务队列面板
        BlockingQueue<Runnable> queue = threadPool.getQueue();
        techTaskQueuePanel = new TechTaskQueuePanel(queue);
        JPanel queueWrapper = new JPanel(new BorderLayout());
        queueWrapper.setOpaque(false);
        queueWrapper.add(techTaskQueuePanel, BorderLayout.CENTER);

        // 任务提交面板
        JPanel taskPanel = createTechPanel("任务提交", new Color(25, 35, 55));
        taskPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

        JLabel taskCountLabel = createTechLabel("任务数量:");
        taskCountSpinner = createTechSpinner(10, 1, 100);

        taskPanel.add(taskCountLabel);
        taskPanel.add(taskCountSpinner);

        // 日志区域
        JPanel logPanel = createTechPanel("执行日志", new Color(25, 35, 55));
        logPanel.setLayout(new BorderLayout());

        logArea = new JTextArea();
        logArea.setEditable(false);
        logArea.setFont(new Font("Consolas", Font.PLAIN, 14));
        JScrollPane scrollPane = new JScrollPane(logArea);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        scrollPane.getViewport().setBackground(new Color(25, 35, 55));

        logPanel.add(scrollPane, BorderLayout.CENTER);

        // 添加所有组件到内容面板
        contentPanel.add(leftPanel, BorderLayout.WEST);
        contentPanel.add(queueWrapper, BorderLayout.CENTER);
        contentPanel.add(logPanel, BorderLayout.EAST);

        // 底部面板
        JPanel bottomPanel = new JPanel(new BorderLayout());
        bottomPanel.setOpaque(false);
        bottomPanel.add(taskPanel, BorderLayout.CENTER);

        // 添加内容面板和底部面板到主面板
        mainPanel.add(contentPanel, BorderLayout.CENTER);
        mainPanel.add(bottomPanel, BorderLayout.SOUTH);

        // 添加主面板到窗口
        add(mainPanel);
    }

    private JPanel createTechPanel(String title, Color bgColor) {
        JPanel panel = new JPanel();
        panel.setBackground(bgColor);
        panel.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createLineBorder(PRIMARY, 1, true),
                title
        ));
        return panel;
    }

    private JLabel createTechLabel(String text) {
        JLabel label = new JLabel(text);
        label.setForeground(TEXT_COLOR);
        label.setFont(new Font("微软雅黑", Font.BOLD, 14));
        return label;
    }

    private JLabel createTechValueLabel(String text) {
        JLabel label = new JLabel(text);
        label.setForeground(ACCENT);
        label.setFont(new Font("Consolas", Font.BOLD, 14));
        return label;
    }

    private JSpinner createTechSpinner(int value, int min, int max) {
        SpinnerNumberModel model = new SpinnerNumberModel(value, min, max, 1);
        JSpinner spinner = new JSpinner(model);
        spinner.setFont(new Font("Consolas", Font.BOLD, 14));
        spinner.setBackground(new Color(35, 45, 65));
        spinner.setForeground(ACCENT);
        spinner.setBorder(BorderFactory.createLineBorder(PRIMARY, 1));

        // 自定义编辑器
        JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner);
        editor.getTextField().setBackground(new Color(35, 45, 65));
        editor.getTextField().setForeground(ACCENT);
        editor.getTextField().setCaretColor(PRIMARY);
        spinner.setEditor(editor);

        return spinner;
    }

    private JButton createTechButton(String text, Color color) {
        JButton button = new JButton(text) {
            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 绘制渐变背景
                GradientPaint gradient = new GradientPaint(
                        0, 0, color.darker(),
                        0, getHeight(), color.brighter()
                );
                g2d.setPaint(gradient);
                g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 15, 15);

                // 绘制发光边框
                g2d.setColor(color);
                g2d.setStroke(new BasicStroke(2));
                g2d.drawRoundRect(1, 1, getWidth()-2, getHeight()-2, 15, 15);

                // 绘制文字
                g2d.setColor(Color.WHITE);
                g2d.setFont(new Font("微软雅黑", Font.BOLD, 14));
                FontMetrics fm = g2d.getFontMetrics();
                int x = (getWidth() - fm.stringWidth(text)) / 2;
                int y = (getHeight() - fm.getHeight()) / 2 + fm.getAscent();
                g2d.drawString(text, x, y);
            }
        };

        button.setContentAreaFilled(false);
        button.setBorderPainted(false);
        button.setFocusPainted(false);
        button.setPreferredSize(new Dimension(120, 40));

        // 添加鼠标悬停效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                button.setCursor(new Cursor(Cursor.HAND_CURSOR));
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                button.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        });

        return button;
    }

    // 渐变背景面板
    private static class GradientPanel extends JPanel {
        private Color color1;
        private Color color2;

        public GradientPanel(Color color1, Color color2) {
            this.color1 = color1;
            this.color2 = color2;
            setOpaque(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            // 创建渐变
            GradientPaint gradient = new GradientPaint(
                    0, 0, color1,
                    getWidth(), getHeight(), color2
            );
            g2d.setPaint(gradient);
            g2d.fillRect(0, 0, getWidth(), getHeight());
        }
    }

    private void startStatusTimer() {
        timer = new Timer(50, e -> {
            updateStatus();
            techTaskQueuePanel.refresh();
        });
        timer.start();
    }

    private void updateStatus() {
        // 更新状态标签
        activeThreadsLabel.setText(String.valueOf(threadPool.getActiveCount()));
        queueSizeLabel.setText(String.valueOf(threadPool.getQueue().size()));
        completedTasksLabel.setText(String.valueOf(threadPool.getCompletedTaskCount()));

        // 更新状态标签
        if (threadPool.isShutdown()) {
            stateLabel.setText("已关闭");
            stateLabel.setForeground(SECONDARY);
        } else {
            stateLabel.setText("运行中");
            stateLabel.setForeground(ACCENT);
        }
    }

    private void startThreadPool() {
        if (threadPool != null && !threadPool.isShutdown()) {
            log("线程池已在运行中");
            return;
        }

        int coreSize = (Integer) corePoolSizeSpinner.getValue();
        int maxSize = (Integer) maxPoolSizeSpinner.getValue();

        threadPool = new ThreadPool(
                coreSize, maxSize, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(100),
                new DefaultThreadFactory(),
                new AbortPolicy()
        );

        log("线程池已启动 (核心线程: " + coreSize + ", 最大线程: " + maxSize + ")");
    }

    private void stopThreadPool() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池已关闭或未启动");
            return;
        }

        threadPool.shutdown();
        log("线程池关闭中...");

        // 在后台等待线程池关闭
        new Thread(() -> {
            try {
                threadPool.awaitTermination(5, TimeUnit.SECONDS);
                log("线程池已完全关闭");
            } catch (InterruptedException ex) {
                log("线程池关闭被中断");
            }
        }).start();
    }

    private void resizeThreadPool() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池未启动，请先启动线程池");
            return;
        }

        int newCoreSize = (Integer) corePoolSizeSpinner.getValue();
        int newMaxSize = (Integer) maxPoolSizeSpinner.getValue();

        threadPool.setCorePoolSize(newCoreSize);
        threadPool.setMaximumPoolSize(newMaxSize);

        log("线程池已调整 (新核心线程: " + newCoreSize + ", 新最大线程: " + newMaxSize + ")");
    }

    private void submitTasks() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池未启动或已关闭，无法提交任务");
            return;
        }

        int taskCount = (Integer) taskCountSpinner.getValue();
        log("提交 " + taskCount + " 个任务");

        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            threadPool.execute(() -> {
                String threadName = Thread.currentThread().getName();
                log("任务 " + taskId + " 开始执行 (" + threadName + ")");

                try {
                    // 模拟任务执行时间 (1-3秒)
                    int duration = 1000 + (int)(Math.random() * 2000);
                    Thread.sleep(duration);

                    log("任务 " + taskId + " 完成 (" + threadName + ")");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log("任务 " + taskId + " 被中断 (" + threadName + ")");
                }
            });
        }
    }

    private void log(String message) {
        SwingUtilities.invokeLater(() -> {
            logArea.append(message + "\n");
            // 自动滚动到最后一行
            logArea.setCaretPosition(logArea.getDocument().getLength());
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            TechThreadPoolVisualizer visualizer = new TechThreadPoolVisualizer();
            visualizer.setVisible(true);
        });
    }
}
